
import useService from "@/hooks/useService";

import { lowcodeDebounceAsync } from "../utils";
import type { LowcodeValidateItemCFG } from "../interface";
import type { ValidatorHookProxy, ValidatorProxy, ValidateSqlFetch, ValidateFetchScriptRes } from "./interface";
import { LOWCODERUNTIMEUNIQUEKEY, lowcodeDebounceTime } from "../constant";

const useLowcodeValidator = (hookProxy?: ValidatorHookProxy) => {
  // const { itemsConfig } = hookProxy || {};
  const mainService = useService({ prefix: "mainApi" });

  const handleValidatorDebounce = async (proxy: ValidatorProxy) => {
    const { value, valType, fieldConf, rowData } = proxy;
  
    let failTypMsgItem: LowcodeValidateItemCFG = null;
	const validateItems = fieldConf?.c_datavalidate?.validateItems;
  
    uni.showLoading({ title: "正在验证数据，请稍等......", mask: true });
    for (let i = 0; i < validateItems?.length; i++) {
      if (failTypMsgItem) {
        break;
      }
      const { type, failMsg, failType, groups, validateSqlCFG } = validateItems[i];
      if (type === "1") { // 本地校验
        const groupLocalValidateRes = groups?.some(gItem => { // groupLocalValidateRes 为true，报错
          const itemValidateRes = gItem.ruleItems?.every(ri => { // 最内层的且，都通过才报错
            let logicRes = null;
            if (!ri?.uuid || !ri?.logic) {
              return true;
            }
            switch (ri?.logic) {  // !!! 当前条件下报这个错，正则除外 !!!    等于的时候报错，不等于就是校验通过
              case "等于":
                {
                  logicRes = valType === "number" ? (value === 0 ? "0" : ((value || "") + "")) === ri.value : value === ri.value;
                }
                break;
              case "大于":
                {
                  logicRes = valType === "number" ? (+value || 0) > (+ri.value || 0) : value > ri.value;
                }
                break;
              case "小于":
                {
                  logicRes = valType === "number" ? (+value || 0) < (+ri.value || 0) : value < ri.value;
                }
                break;
              case "相似":
              case "包含":
                {
                  logicRes = value?.includes?.(ri?.value);
                }
                break;
              case "不相似":
              case "不包含":
                {
                  logicRes = !value?.includes?.(ri?.value);
                }
                break;
              case "左相似":
                {
                  logicRes = value?.startsWith?.(ri?.value);
                }
                break;
              case "为空":
                {
                  logicRes = !value && value !== 0;
                }
                break;
              case "不为空":
                {
                  logicRes = !!value || value === 0;
                }
                break;
              case "长度等于":
                {
                  const lgEqual = value === 0 ? "1" : ((value || "") + "")?.length + "";
                  logicRes = lgEqual === ri.value;
                }
                break;
              case "长度最小":
                {
                  const lgMin = value === 0 ? "1" : ((value || "") + "")?.length + "";
                  logicRes = lgMin >= ri.value;
                }
                break;
              case "长度最大":
                {
                  const lgMax = value === 0 ? "1" : ((value || "") + "")?.length + "";
                  logicRes = lgMax <= ri.value;
                }
                break;
              case "位数等于":
                {
                  // TODO 应该是不包含此项
                }
                break;
              case "正则表达式":
                {
                  const reg = new RegExp(ri.value);
                  logicRes = !reg?.test?.(value);
                }
                break;
              default:
                break;
            }
  
            return logicRes;
          }); // 最内层的且，都正确才正确
          return itemValidateRes;
        });
  
        if (groupLocalValidateRes) {
          failTypMsgItem = validateItems[i];
        }
      } else if (type === "2") { // 接口验证
        // if (!groupApiValidateRes) {
        //   failTypMsgItem = validateItems[i];
        // }
      } else if (type === "3") { // 自定义脚本验证
        const { service, sql } = validateSqlCFG || {};

        const fetchReqProxy = { ModuleCode: hookProxy?.mdCode || "" };
        const mergeReq = typeof rowData === "object" ? { RowData: rowData } : {}; // WhereList
        const fetchReq: ValidateSqlFetch = { ValidateSql: sql, ...mergeReq, ServiceName: service };
        const fetchResObj = await mainService.request<ValidateSqlFetch, ValidateFetchScriptRes>(LOWCODERUNTIMEUNIQUEKEY, "ValidateData", fetchReq, "", "", fetchReqProxy);

        if (!fetchResObj) {
          failTypMsgItem = { failMsg: "数据验证失败！" };
        } else if (fetchResObj?.Flag === "0") {
          failTypMsgItem = { failMsg: fetchResObj?.ErrorMsg || "数据验证失败！" }
        }
      }
    } // for loop end

	const condition1=['text','dialoginput','multitext','richtext']?.includes(fieldConf?.c_type);
	if(condition1){
		const dbLength = fieldConf?.bindFieldDBLength;
		if(dbLength && value?.length >dbLength){
			failTypMsgItem ={ failMsg:"不能超过"+dbLength+"个字符!"};
		}
	}

    // console.log("ruleValidator ", validateItems, failTypMsgItem);
    uni.hideLoading();

    return { validated: !failTypMsgItem, msg: failTypMsgItem?.failMsg };
    // failTypMsgItem ? reject(failTypMsgItem.failMsg) : resole(value);
  };

  const handleValidator = lowcodeDebounceAsync(handleValidatorDebounce, lowcodeDebounceTime);

  return { handleValidator };
}

export default useLowcodeValidator;
